/** 浏览器窗体相关函数
 * @file wkewnd.hpp
 * @author Kiven Lee
 * @version 1.0
 * @date 2021-11-15
 *
 * @copyright Kivensoft (c) 2018 - 2021
 *
 */

#include "wkewnd.hpp"

#include <commctrl.h>

#include <wke.h>

#include "kwin/path.hpp"
#include "klib/log.hpp"
#include "config.hpp"
#include "jsfuncs.hpp"

using namespace miniplayer;

static std::string home_url;

[[maybe_unused]]
static LRESULT CALLBACK subClassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
        UINT_PTR uIdSubclass, DWORD_PTR dwRefData) {
    switch (wParam) {
        default:
            return ::DefSubclassProc(hWnd, uMsg, wParam, lParam);
    }
    return 0;
}

// 回调：点击了关闭、返回 true 将销毁窗口，返回 false 什么都不做。
static bool handleWindowClosing(wkeWebView webWindow, void* param) {
    // return IDYES == Config::show_message("确定要退出播放器吗？", MB_YESNO | MB_ICONQUESTION);
    return true;
}

// 回调：窗口已销毁
static void handleWindowDestroy(wkeWebView webWindow, void* param) {
    PostQuitMessage(0);
}

// 回调：文档加载成功
static void handleDocumentReady(wkeWebView webWindow, void* param) {
    wkeShowWindow(webWindow, true);
    ::SetFocus(WkeWnd::getWkeHWND());
}

// 回调：页面标题改变
static void handleTitleChanged(wkeWebView webWindow, void* param, const wkeString title) {
    wkeSetWindowTitle(webWindow, wkeGetString(title));
}

// 回调：创建新的页面，比如说调用了 window.open 或者点击了 <a target="_blank" .../>
static wkeWebView handleCreateView(wkeWebView webWindow, void* param, wkeNavigationType navType,
        const wkeString url, const wkeWindowFeatures* features) {
    wkeWebView newWindow = wkeCreateWebWindow(WKE_WINDOW_TYPE_POPUP, NULL,
            features->x, features->y, features->width, features->height);
    wkeShowWindow(newWindow, true);
    return newWindow;
}

[[maybe_unused]]
static void readJsFile(const char* path, std::vector<char>* buffer) {
//     HANDLE hFile = CreateFile(path, GENERIC_READ, FILE_SHARE_READ,
//             NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

//     if (INVALID_HANDLE_VALUE == hFile) {
//         DebugBreak();
//         return;
//     }

//     DWORD fileSizeHigh;
//     const DWORD bufferSize = ::GetFileSize(hFile, &fileSizeHigh);

//     DWORD numberOfBytesRead = 0;
//     buffer->resize(bufferSize);
//     ::ReadFile(hFile, &buffer->at(0), bufferSize, &numberOfBytesRead, nullptr);
//     ::CloseHandle(hFile);
}

static bool handleLoadUrlBegin(wkeWebView webView, void* param, const char* url, void *job) {
    // if (strncmp(url, "http://localhost:12222", 22) == 0) {
    //     wkeNetSetMIMEType(job, (char*)"text/html");
    //     wkeNetSetData(job, (char*)"\"test1111\"", 10);
    //     return true;
    // }
    // if (strcmp(url, "http://www.baidu.com/") == 0) {
    //     wkeNetHookRequest(job);
    // }
    return false;
}

static void handleLoadUrlEnd(wkeWebView webView, void* param, const char *url, void *job, void* buf, int len) {
    // const char *str = "百度一下";
    // const char *str1 = "谷歌一下";
    // const char *b = strstr(static_cast<const char*>(buf), str);
    // memcpy((void *)b, str1, strlen(str1));
}

// 互相调用：CPP调用JS
[[maybe_unused]]
static const char* callJSFunc(jsExecState es, char *funcName, char *param) {
    // jsValue f = jsGetGlobal(es, funcName);
    // jsValue val = jsString(es, param);
    // jsValue callRet = jsCallGlobal(es, f, &val, 1);
    // return jsToString(es, callRet);
    return nullptr;
}

bool WkeWnd::createWebWindow() {
    #define MY_JS_BIND_FUNC(NAME, ARG_COUNT) wkeJsBindFunction(#NAME, &js_##NAME, nullptr, ARG_COUNT)
    MY_JS_BIND_FUNC(msgbox, 1);
    MY_JS_BIND_FUNC(quitApp, 0);
    MY_JS_BIND_FUNC(showWindow, 0);
    MY_JS_BIND_FUNC(vlcPlay, 1);
    MY_JS_BIND_FUNC(vlcPlayUrl, 1);
    MY_JS_BIND_FUNC(vlcStop, 0);
    MY_JS_BIND_FUNC(vlcPause, 0);
    MY_JS_BIND_FUNC(listFiles, 1);
    MY_JS_BIND_FUNC(loadFile, 1);
    #undef MY_JS_BIND_FUNC

    wkeJsBindGetter("vlcPlayer", &js_get_vlcPlayer, nullptr);

    kwin::Rect rc;
    rc.getClient(Config::main_hwnd);

    wkeWebView& wwv_ctrl = Config::wke_web_view;
    wwv_ctrl = wkeCreateWebWindow(WKE_WINDOW_TYPE_CONTROL, Config::main_hwnd,
            rc.left, rc.top, rc.width(), rc.height());
    if (!wwv_ctrl) return false;
    // ::SetWindowSubclass(wkeGetWindowHandle(wwv_ctrl), subClassProc, 0, 0);

    wkeSetCspCheckEnable(wwv_ctrl, false); // 打开允许跨域请求
    wkeSetTouchEnabled(wwv_ctrl, true); // 允许转换触屏消息
    // wkeSetTransparent(wwv_ctrl, true); // 设置透明模式

    // wkeSetWindowTitle(wkeWebView, Config::get_app());

    #define MY_WKE_HANDLE(NAME) wkeOn##NAME(wwv_ctrl, handle##NAME, NULL)
    MY_WKE_HANDLE(WindowClosing);
    MY_WKE_HANDLE(WindowDestroy);
    MY_WKE_HANDLE(DocumentReady);
    MY_WKE_HANDLE(TitleChanged);
    MY_WKE_HANDLE(CreateView);
    MY_WKE_HANDLE(LoadUrlBegin);
    MY_WKE_HANDLE(LoadUrlEnd);
    #undef MY_WKE_HANDLE

    // wkeSetDebugConfig(wkeWebView, "decodeUrlRequest", nullptr);

    // wkeMoveToCenter(webWindow);
    // wkeLoadURL(webWindow, "http://www.baidu.com");
    // wkeLoadURL(webWindow, "about:blank");

    klib::dstring_t<256> path;
    std::string_view idx_html = Config::get_index_html();
    if (std::strstr(idx_html.data(), "://")) {
        home_url = idx_html.data();
    } else {
        if (kwin::absPathFromApp(path, idx_html) == 0) {
            Config::msgbox("界面文件不存在: %s", idx_html.data());
            return false;
        }
        home_url = path.data();
    }
    wkeLoadURL(wwv_ctrl, home_url.c_str());
    wkeShowWindow(wwv_ctrl, true);

    return true;
}

HWND WkeWnd::getWkeHWND() {
    return wkeGetWindowHandle(Config::wke_web_view);
}

void WkeWnd::goHome() {
    // const char* url = wkeGetURL(Config::wke_web_view);
    wkeLoadURL(Config::wke_web_view, home_url.c_str());
}
